package Storage;

import java.text.ParseException;

import Object.DSException;
import Object.DSQuery;
import Task.DSTask;
import Task.DSTaskList;

//@author A0103535R
/************************************ Abstract Class DSTaskStore ***************************/
public class DSTaskStore {
        private static DSTaskStore _taskStore = null;
        private DSTaskList _taskList = null;
        private DSDataFileHandler _dataFileHandler = null;
        
    	/**
    	 * This is the constructor of DSTaskStore.
    	 * 
    	 * @throws DSException
    	 */
        private DSTaskStore( ) throws DSException{
                if(_dataFileHandler == null){
                        _dataFileHandler = DSDataFileHandler.getInstance();
                        assert _dataFileHandler != null;
                }
                _taskList = _dataFileHandler.loadFromDataFile();
                assert _taskList != null;
        }
        
    	/**
    	 * This function is used to get the instance singleton of DSTaskStore
    	 * 
    	 * @return the singleton instance of DSTaskStore
    	 * 
    	 * @throws DSException
    	 */
        public static DSTaskStore getInstance() throws DSException{
                if(_taskStore == null){
                        _taskStore = new DSTaskStore();
                }
                assert _taskStore != null;
                return _taskStore;
        }
        
    	/**
    	 * This function is used to add new task in task store
    	 * 
    	 * @param task
    	 * 			task to add in task store.
    	 * 
    	 * @return result of process
    	 * 
    	 * @throws DSException
    	 */
        public boolean add(DSTask task) throws DSException{             
                if(_taskList.add(task)){
                        if(updateToFile(_taskList)){
                                return true;
                        }
                }
                return false;
        }
        
    	/**
    	 * This function is used to remove task with specific id from task store.
    	 * 
    	 * @param taskId
    	 * 			taskId of task to remove.
    	 * 
    	 * @return the task removed.
    	 * 
    	 * @throws DSException
    	 */
        public DSTask remove(String taskId) throws DSException{
                assert taskId != null;
                int i = _taskList.indexOf(taskId);
                if(i>=0){
                        DSTask oldTask = _taskList.remove(i);
                        if(updateToFile(_taskList)){
                                return oldTask;
                        }
                }
                return null;
        }
        
    	/**
    	 * This function is used to update task in task id.
    	 * 
    	 * @return the old task.
    	 * 
    	 * @throws DSException
    	 */
        public DSTask update(DSTask newTask) throws DSException{
                int i = _taskList.indexOf(newTask);
                if(i >= 0){
                        DSTask oldTask = _taskList.set(i, newTask);
                        if(updateToFile(_taskList)){
                                return oldTask;
                        }
                }
                return null;
        }
        
    	/**
    	 * This function is used to search tasks in task store.
    	 * 
    	 * @return task list of task meeting the requirement.
    	 */
        public DSTaskList search(DSQuery query) {
                try {
                        return DSQueryExecuter.executeQuery(_taskList.copy(), query);
                } catch (ParseException e) {
                        e.printStackTrace();
                }
                return null;
        }
        
    	/**
    	 * This function is used to clear all tasks in task store.
    	 * 
    	 * @throws DSException
    	 */
        public void clearAll() throws DSException{
                _taskList = new DSTaskList();
                updateToFile(_taskList);
        }
        
    	/**
    	 * This function is used to update tasks to local file.
    	 * 
    	 * @param taskList
    	 * 			taskList to update to local file.
    	 * 
    	 * @return result of process.
    	 * 
    	 * @throws DSException
    	 */
        private boolean updateToFile(DSTaskList taskList) throws DSException{
                if(taskList == null)
                        return false;
                return _dataFileHandler.saveToDataFile(_taskList);
        }

    	/**
    	 * This function is used to get all tasks stored in task store.
    	 * 
    	 * @return all tasks in task store.
    	 * 
    	 * @throws DSException
    	 */
        public DSTaskList getTaskList() throws DSException {
        	try {
                DSTaskList list = _taskList.copy();
                return list;
			} catch (ParseException e) {
				throw new DSException(DSException.EXCEPTION_MESSAGE_DSTASKSTORE_GET_TASK_LIST);
			}
        }
}